﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Text;
using System.Threading.Tasks;

namespace Get_NAV
{
    public sealed class Modeltools
    {
        public PSCommand Commands { get; set; }

        #region Modeltools

        private void BasicCompileNAVApplicationObject(ushort overload, string databaseName,
            string password, string username, Dictionary<ModelParameters, object> parameters)
        {
            Command compileCommand = new Command("Compile-NAVApplicationObject");
            compileCommand.Parameters.Add("DatabaseName", databaseName);
            if (overload > 0)
            {
                compileCommand.Parameters.Add("Password", password);
                compileCommand.Parameters.Add("Username", username);
            }

            foreach (var item in parameters)
            {
                compileCommand.Parameters.Add(item.Key.ToString(), item.Value);
            }


            Commands.AddCommand(compileCommand);

        }
        #region overload CompileNAVApplicationObject
        public void CompileNAVApplicationObject(string databaseName, Dictionary<ModelParameters, object> parameters)
        {
            BasicCompileNAVApplicationObject(0, databaseName, null, null, parameters);
        }
        public void CompileNAVApplicationObject(string databaseName, string password, string username, Dictionary<ModelParameters, object> parameters)
        {
            BasicCompileNAVApplicationObject(1, databaseName, password, username, parameters);
        }
        #endregion overload CompileNAVApplicationObject

        private void BasicCreateNAVDatabase(ushort overload, string databaseName,
            string password, string username, Dictionary<ModelParameters, object> parameters)
        {
            Command createCommand = new Command("Create-NAVDatabase");

            createCommand.Parameters.Add("DatabaseName", databaseName);
            if (overload > 0)
            {
                createCommand.Parameters.Add("Password", password);
                createCommand.Parameters.Add("Username", username);
            }

            foreach (var item in parameters)
            {
                createCommand.Parameters.Add(item.Key.ToString(), item.Value);
            }

            Commands.AddCommand(createCommand);
        }
        #region overloads CreateNAVDatabase
        public void CreateNAVDatabase(string databaseName, Dictionary<ModelParameters, object> parameters)
        {
            BasicCreateNAVDatabase(0, databaseName, null, null, parameters);
        }
        public void CreateNAVDatabase(string databaseName, string password, string username, Dictionary<ModelParameters, object> parameters)
        {
            BasicCreateNAVDatabase(1, databaseName, password, username, parameters);
        }
        #endregion overloads CreateNAVDatabase

        private void BasicDeleteNAVApplicationObject(ushort overload, string databaseName,
            string password, string username, Dictionary<ModelParameters, object> parameters)
        {
            Command deleteCommand = new Command("Delete-NAVApplicationObject");

            deleteCommand.Parameters.Add("DatabaseName", databaseName);
            if (overload > 0)
            {
                deleteCommand.Parameters.Add("Password", password);
                deleteCommand.Parameters.Add("Username", username);
            }

            foreach (var item in parameters)
            {
                deleteCommand.Parameters.Add(item.Key.ToString(), item.Value);
            }

            Commands.AddCommand(deleteCommand);
        }
        #region overload DeleteNAVApplicationObject
        public void DeleteNAVApplicationObject(string databaseName, Dictionary<ModelParameters, object> parameters)
        {
            BasicDeleteNAVApplicationObject(0, databaseName, null, null, parameters);
        }
        public void DeleteNAVApplicationObject(string databaseName, string password, string username, Dictionary<ModelParameters, object> parameters)
        {
            BasicDeleteNAVApplicationObject(1, databaseName, password, username, parameters);
        }
        #endregion overload DeleteNAVApplicationObject

        private void BasicExportNAVApplicationObject(ushort overload, string databaseName, string path,
            string password, string username, Dictionary<ModelParameters, object> parameters)
        {
            Command exportCommand = new Command("Export-NAVApplicationObject");

            exportCommand.Parameters.Add("DatabaseName", databaseName);
            exportCommand.Parameters.Add("Path", path);

            if (overload > 0)
            {
                exportCommand.Parameters.Add("Password", password);
                exportCommand.Parameters.Add("Username", username);
            }

            foreach (var item in parameters)
            {
                exportCommand.Parameters.Add(item.Key.ToString(), item.Value);
            }

            Commands.AddCommand(exportCommand);
        }
        #region overload ExportNAVApplicationObject
        public void ExportNAVApplicationObject(string databaseName, string path, Dictionary<ModelParameters, object> parameters)
        {
            BasicExportNAVApplicationObject(0, databaseName, path, null, null, parameters);
        }
        public void ExportNAVApplicationObject(string databaseName, string path, string password, string username, Dictionary<ModelParameters, object> parameters)
        {
            BasicExportNAVApplicationObject(1, databaseName, path, password, username, parameters);
        }
        #endregion overload ExportNAVApplicationObject

        private void BasicImportNAVApplicationObject(ushort overload, string databaseName, string path,
            string password, string username, Dictionary<ModelParameters, object> parameters)
        {
            Command importCommand = new Command("Import-NAVApplicationObject");

            importCommand.Parameters.Add("DatabaseName", databaseName);
            importCommand.Parameters.Add("Path", path);

            if (overload > 0)
            {
                importCommand.Parameters.Add("Password", password);
                importCommand.Parameters.Add("Username", username);
            }

            foreach (var item in parameters)
            {
                importCommand.Parameters.Add(item.Key.ToString(), item.Value);
            }

            Commands.AddCommand(importCommand);
        }
        #region overload ImportNAVApplicationObject
        public void ImportNAVApplicationObject(string databaseName, string path, Dictionary<ModelParameters, object> parameters)
        {
            BasicImportNAVApplicationObject(0, databaseName, path, null, null, parameters);
        }
        public void ImportNAVApplicationObject(string databaseName, string path, string password, string username, Dictionary<ModelParameters, object> parameters)
        {
            BasicImportNAVApplicationObject(1, databaseName, path, password, username, parameters);
        }
        #endregion overload ImportNAVApplicationObject

        private void BasicInvokeNAVDatabaseConversion(ushort overload, string databaseName,
            string password, string username, Dictionary<ModelParameters, object> parameters)
        {
            Command invokeCommand = new Command("Invoke-NAVDatabaseConversion");

            invokeCommand.Parameters.Add("DatabaseName", databaseName);
            if (overload > 0)
            {
                invokeCommand.Parameters.Add("Password", password);
                invokeCommand.Parameters.Add("Username", username);
            }

            foreach (var item in parameters)
            {
                invokeCommand.Parameters.Add(item.Key.ToString(), item.Value);
            }

            Commands.AddCommand(invokeCommand);
        }
        #region overload InvokeNAVDatabaseConversion 
        public void InvokeNAVDatabaseConversion(string databaseName, Dictionary<ModelParameters, object> parameters)
        {
            BasicInvokeNAVDatabaseConversion(0, databaseName, null, null, parameters);
        }
        public void InvokeNAVDatabaseConversion(string databaseName, string password, string username, Dictionary<ModelParameters, object> parameters)
        {
            BasicInvokeNAVDatabaseConversion(1, databaseName, password, username, parameters);
        }
        #endregion overload InvokeNAVDatabaseConversion

        public void CompareNAVApplicationObject(string deltaPath, string modifiedPath, string originalPath,
            Dictionary<ModelParameters, object> parameters)
        {
            Command compareCommand = new Command("Compare-NAVApplicationObject");
            compareCommand.Parameters.Add("DeltaPath", deltaPath);
            compareCommand.Parameters.Add("ModifiedPath", modifiedPath);
            compareCommand.Parameters.Add("OriginalPath", originalPath);

            foreach (var item in parameters)
            {
                compareCommand.Parameters.Add(item.Key.ToString(), item.Value);
            }

            Commands.AddCommand(compareCommand);
        }

        public void ExportNAVApplicationObjectLanguage(string destination, string source,
            Dictionary<ModelParameters, object> parameters)
        {
            Command exportCommand = new Command("Export-NAVApplicationObjectLanguage");
            exportCommand.Parameters.Add("Destination", destination);
            exportCommand.Parameters.Add("Source", source);

            foreach (var item in parameters)
            {
                exportCommand.Parameters.Add(item.Key.ToString(), item.Value);
            }

            Commands.AddCommand(exportCommand);
        }

        public void GetNAVApplicationObjectProperty(string source)
        {
            Command getCommand = new Command("Get-NAVApplicationObjectProperty");
            getCommand.Parameters.Add("Source", source);

            Commands.AddCommand(getCommand);
        }

        public void ImportNAVApplicationObjectLanguage(string destination, string languagePath, string source,
             Dictionary<ModelParameters, object> parameters)
        {
            Command importCommand = new Command("Import-NAVApplicationObjectLanguage");
            importCommand.Parameters.Add("Destination", destination);
            importCommand.Parameters.Add("LanguagePath", languagePath);
            importCommand.Parameters.Add("Source", source);

            foreach (var item in parameters)
            {
                importCommand.Parameters.Add(item.Key.ToString(), item.Value);
            }

            Commands.AddCommand(importCommand);
        }

        public void JoinNAVApplicationObjectFile(string destination, string source, Dictionary<ModelParameters, object> parameters)
        {
            Command joinCommand = new Command("Join-NAVApplicationObjectFile");
            joinCommand.Parameters.Add("Destination", destination);
            joinCommand.Parameters.Add("Source", source);

            foreach (var item in parameters)
            {
                joinCommand.Parameters.Add(item.Key.ToString(), item.Value);
            }

            Commands.AddCommand(joinCommand);
        }

        public void JoinNAVApplicationObjectLanguageFile(string source, Dictionary<ModelParameters, object> parameters)
        {
            Command joinCommand = new Command("Join-NAVApplicationObjectLanguageFile");
            joinCommand.Parameters.Add("Source", source);

            foreach (var item in parameters)
            {
                joinCommand.Parameters.Add(item.Key.ToString(), item.Value);
            }

            Commands.AddCommand(joinCommand);
        }

        public void MergeNAVApplicationObject(string modifiedPath, string originalPath, string resultPath, string targetPath,
            Dictionary<ModelParameters, object> parameters)
        {
            Command mergeCommand = new Command("Merge-NAVApplicationObject");
            mergeCommand.Parameters.Add("ModifiedPath", modifiedPath);
            mergeCommand.Parameters.Add("OriginalPath", originalPath);
            mergeCommand.Parameters.Add("ResultPath", resultPath);
            mergeCommand.Parameters.Add("TargetPath", targetPath);

            foreach (var item in parameters)
            {
                mergeCommand.Parameters.Add(item.Key.ToString(), item.Value);
            }

            Commands.AddCommand(mergeCommand);
        }

        public void NewNAVCrmTable(string credential, string crmServer, string entityLogicalName, string objectId,
            Dictionary<ModelParameters, object> parameters)
        {
            Command newCommand = new Command("New-NAVCrmTable");
            newCommand.Parameters.Add("Credential", credential);
            newCommand.Parameters.Add("CrmServer", crmServer);
            newCommand.Parameters.Add("EntityLogicalName", entityLogicalName);
            newCommand.Parameters.Add("ObjectId", objectId);

            foreach (var item in parameters)
            {
                newCommand.Parameters.Add(item.Key.ToString(), item.Value);
            }

            Commands.AddCommand(newCommand);
        }

        public void RemoveNAVApplicationObjectLanguage(string destination, string source, Dictionary<ModelParameters, object> parameters)
        {
            Command removeCommand = new Command("Remove-NAVApplicationObjectLanguage");
            removeCommand.Parameters.Add("Destination", destination);
            removeCommand.Parameters.Add("Source", source);

            foreach (var item in parameters)
            {
                removeCommand.Parameters.Add(item.Key.ToString(), item.Value);
            }

            Commands.AddCommand(removeCommand);
        }

        public void SetNAVApplicationObjectProperty(string targetPath, Dictionary<ModelParameters, object> parameters)
        {
            Command setCommand = new Command("Set-NAVApplicationObjectProperty");
            setCommand.Parameters.Add("TargetPath", targetPath);

            foreach (var item in parameters)
            {
                setCommand.Parameters.Add(item.Key.ToString(), item.Value);
            }

            Commands.AddCommand(setCommand);
        }

        public void SplitNAVApplicationObjectFile(string source, Dictionary<ModelParameters, object> parameters)
        {
            Command splitCommand = new Command("Split-NAVApplicationObjectFile");
            splitCommand.Parameters.Add("Source", source);

            foreach (var item in parameters)
            {
                splitCommand.Parameters.Add(item.Key.ToString(), item.Value);
            }

            Commands.AddCommand(splitCommand);
        }

        public void SplitNAVApplicationObjectLanguageFile(string source, Dictionary<ModelParameters, object> parameters)
        {
            Command splitCommand = new Command("Split-NAVApplicationObjectLanguageFile");
            splitCommand.Parameters.Add("Source", source);

            foreach (var item in parameters)
            {
                splitCommand.Parameters.Add(item.Key.ToString(), item.Value);
            }

            Commands.AddCommand(splitCommand);
        }

        public void TestNAVApplicationObjectLanguage(string languageId, string source, Dictionary<ModelParameters, object> parameters)
        {
            Command testCommand = new Command("Test-NAVApplicationObjectLanguage");
            testCommand.Parameters.Add("LanguageId", languageId);
            testCommand.Parameters.Add("Source", source);

            foreach (var item in parameters)
            {
                testCommand.Parameters.Add(item.Key.ToString(), item.Value);
            }

            Commands.AddCommand(testCommand);
        }

        public void UpdateNAVApplicationObject(string deltaPath, string resultPath, string targetPath, Dictionary<ModelParameters, object> parameters)
        {
            Command updateCommand = new Command("Update-NAVApplicationObject");
            updateCommand.Parameters.Add("DeltaPath", deltaPath);
            updateCommand.Parameters.Add("ResultPath", resultPath);
            updateCommand.Parameters.Add("TargetPath", targetPath);

            foreach (var item in parameters)
            {
                updateCommand.Parameters.Add(item.Key.ToString(), item.Value);
            }

            Commands.AddCommand(updateCommand);
        }

        #endregion Modeltools
    }
}

public enum SynchronizeSchemaChanges
{
    Yes,
    No,
    Force
}

public enum ImportAction
{
    Default,
    Overwrite,
    Skip
}

public enum ModelParameters
{
    AsJob,
    Confirm,
    Collation,
    DatabaseServer,
    DateTimeProperty,
    Destination,
    DevelopmentLanguageId,
    DisableCommentOut,
    DocumentationConflict,
    Encoding,
    ExportTxtSkipUnlicensed,
    Filter,
    Force,
    ImportAction,
    LanguageId,
    Legacy,
    LogPath,
    ModifiedProperty,
    Name,
    NavServerInstance,
    NavServerManagementPort,
    NavServerName,
    NoCodeCompression,
    OutputPath,
    PassThru,
    PreserveFormatting,
    Recompile,
    RemoveRedundant,
    Strict,
    SynchronizeSchemaChanges,
    VersionListProperty,
    WhatIf,
}
